package com.astersoft.lib.db;

/*
 * Copyright 2012 AsterSoft personal developer - Licensed under the Apache
 * License, Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
 * or agreed to in writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

import com.astersoft.lib.util.ASBeanUtils;

/**
 * This class makes available static methods for database access and automatic
 * mapping
 * 
 * @author dario durzo
 * @version 0.1
 * @date 28-05-2012
 * 
 */
public class ASDBUtils {
	
	/**
	 * Execute a database update/insert/delete
	 * 
	 * @param connection
	 * @param sqlQuery
	 * @return
	 */
	public static int executeUpdate(String connection, String sqlQuery) {
		return executeUpdate(connection, sqlQuery, false, -1);
	}
	public static int executeUpdate(String connection, String sqlQuery, boolean autocommit) {
		return executeUpdate(connection, sqlQuery, autocommit, -1);
	}
	public static int executeUpdate(String connection, String sqlQuery, boolean autocommit, int transactionIsolation) {
		// get connection
		ASConnectionManager cmgr = new ASConnectionManager();
		Connection conn = cmgr.getConnection(connection, autocommit, transactionIsolation);
		Statement stmt = null;
		int rowCount = -1;
		
		// execute query
		try {
			// create statement
			stmt = conn.createStatement();
			rowCount = stmt.executeUpdate(sqlQuery);
			
			conn.commit();
		} catch (SQLException e) {
			e.printStackTrace();
			rowCount = -1;
		} finally {
			// clean connections
			cmgr.cleanUp(conn, stmt, null);
		}
		
		return rowCount;
	}
	
	/**
	 * Get the data from database
	 * 
	 * @param connection
	 * @param sqlQuery
	 * @param type
	 * @return
	 */
	public static <T> T[] getData(String connection, String sqlQuery, Class<T> type) {
		return getData(connection, sqlQuery, type, null, false, false);
	}

	public static <T> T[] getData(String connection, String sqlQuery, Class<T> type, ASMapperDefaultValues defVal) {
		return getData(connection, sqlQuery, type, defVal, false, false);
	}

	@SuppressWarnings("unchecked")
	public static <T> T[] getData(String connection, String sqlQuery, Class<T> type, ASMapperDefaultValues defVal, boolean logEnabled,
	boolean logNative) {
		// define output data
		List<T> data = null;

		// get connection
		ASConnectionManager cmgr = new ASConnectionManager();
		Connection conn = cmgr.getConnection(connection);
		Statement stmt = null;
		ResultSet rs = null;

		// execute query
		try {
			// create statement
			stmt = conn.createStatement();
			rs = stmt.executeQuery(sqlQuery);

			// get mapper instance
			ASResultsetMapper<T> mapper = ASResultsetMapper.getInstance();
			if (defVal != null)
				mapper.changeDefaultMapper(defVal);
			// mapper.getDefaultMapper().setMapping(defVal);

			try {
				data = mapper.toList(rs, type);

				if (logEnabled) {
					for (T d : data) {
						if (logNative)
							System.out.println(d.toString());
						else
							System.out.println(ASBeanUtils.fullToString(d));
					}
				}
			} catch (ASMapperException e) {
				e.printStackTrace();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			// clean connections
			cmgr.cleanUp(conn, stmt, rs);
		}

		// convert to array
		return (T[]) data.toArray((T[]) java.lang.reflect.Array.newInstance(type, data.size()));
	}
}
